package com.talkyun.utils;

import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicInteger;

import static java.util.concurrent.TimeUnit.SECONDS;

public class ExecutorBuilder {
    private static class SimpleThreadFactory implements ThreadFactory {
        private AtomicInteger no = new AtomicInteger(0);
        private String name;

        SimpleThreadFactory(String name) {
            this.name = name;
        }

        @Override
        public Thread newThread(Runnable r) {
            Thread t = new Thread(r, name + "-" + no.incrementAndGet());
            t.setDaemon(true);
            return t;
        }
    }

    private RejectedExecutionHandler handler = new ThreadPoolExecutor.CallerRunsPolicy();
    private BlockingQueue<Runnable> workQueue;
    private String prefix;
    private int corePoolSize;
    private int maxPoolSize;

    public ExecutorBuilder prefix(String prefix) {
        this.prefix = prefix;
        return this;
    }

    public ExecutorBuilder queue(BlockingQueue<Runnable> workQueue) {
        this.workQueue = workQueue;
        return this;
    }

    public ExecutorBuilder minPoolSize(int corePoolSize) {
        this.corePoolSize = corePoolSize;
        return this;
    }

    public ExecutorBuilder maxPoolSize(int maxPoolSize) {
        this.maxPoolSize = maxPoolSize;
        return this;
    }

    public ExecutorBuilder rejectedHandler(RejectedExecutionHandler handler) {
        this.handler = handler;
        return this;
    }

    public ExecutorService build() {
        ThreadFactory threadFactory = new SimpleThreadFactory(prefix == null ? "openx-b" : prefix);
        workQueue = workQueue == null ? new LinkedBlockingQueue<Runnable>() : workQueue;
        int min = corePoolSize == 0 ? 1 : corePoolSize;
        int max = maxPoolSize == 0 ? min : maxPoolSize;
        return new ThreadPoolExecutor(min, max, 60, SECONDS, workQueue, threadFactory, handler);
    }
}